/*
 * VentanaPrincipal.java
 * 
 * Copyright (C) 2008 David Castellanos Serrano
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package dpoo.gui;

import dpoo.control.*;
import dpoo.figuras.*;

import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;

/**
 *
 * @author  david
 */
public class VentanaPrincipal extends javax.swing.JFrame {

    Control control = Control.instance();
    FiguraClase claseSeleccionada = null;
    
    //Cuadros de diálogo
    AcercaDe acercaDeDialog;
    
    //Modelos de los JLists
    DefaultListModel metodosListModel;
    DefaultListModel atributosListModel;
    
    /** Creates new form VentanaPrincipal */
    public VentanaPrincipal() {
        //informo al control que se ha creado la ventana principal
        this.control.setVentanaPrincipal(this);
        this.control.cambiarModoSeleccionar();

        //inicalizo los cuadros de diálogo que usaré posteriormente
        this.acercaDeDialog = new AcercaDe(this, true);
        this.acercaDeDialog.pack();
        
        //inicializo los componentes
        initComponents();
        initCheckNombre();
        
        //instancio los modelos y los asocio a sus respectivos JList
        this.metodosListModel = new DefaultListModel();
        this.jListMetodos.setModel(this.metodosListModel);
        this.atributosListModel = new DefaultListModel();
        this.jListAtributos.setModel(this.atributosListModel);

        //desactivo los elementos de la UI
        this.panelClaseSetEnabled(false);
        this.panelMetodosSetEnabled(false);
        this.metodosModEliSetEnabled(false);
        this.panelAtributosSetEnabled(false);
        this.atributosModEliSetEnabled(false);
    }
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        toggleGroup = new javax.swing.ButtonGroup();
        visibilidadGroup = new javax.swing.ButtonGroup();
        modificadoresGroup = new javax.swing.ButtonGroup();
        statusBar = new javax.swing.JLabel();
        jToolBar = new javax.swing.JToolBar();
        toggleSeleccionar = new javax.swing.JToggleButton();
        toggleClase = new javax.swing.JToggleButton();
        toggleHerencia = new javax.swing.JToggleButton();
        compilar = new javax.swing.JButton();
        jSplitPane = new javax.swing.JSplitPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        jEditorPane = new javax.swing.JEditorPane();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jScrollPaneClase = new javax.swing.JScrollPane();
        jPanelClase = new javax.swing.JPanel();
        claseNombreLabel = new javax.swing.JLabel();
        claseNombre = new javax.swing.JTextField();
        claseHeredaDeLabel = new javax.swing.JLabel();
        claseHeredaDe = new javax.swing.JTextField();
        claseVisiLabel = new javax.swing.JLabel();
        claseVisiPublica = new javax.swing.JRadioButton();
        claseVisiPrivada = new javax.swing.JRadioButton();
        claseVisiPaquete = new javax.swing.JRadioButton();
        claseVisiProtegido = new javax.swing.JRadioButton();
        claseModLabel = new javax.swing.JLabel();
        claseModAbstracta = new javax.swing.JCheckBox();
        claseModFinal = new javax.swing.JCheckBox();
        claseRestaurar = new javax.swing.JButton();
        claseGuardar = new javax.swing.JButton();
        jScrollPaneMetodos = new javax.swing.JScrollPane();
        jPanelMetodos = new javax.swing.JPanel();
        metodosLabel = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        jListMetodos = new javax.swing.JList();
        metodosAnadir = new javax.swing.JButton();
        metodosModificar = new javax.swing.JButton();
        metodosEliminar = new javax.swing.JButton();
        jScrollPaneAtributos = new javax.swing.JScrollPane();
        jPanelAtributos = new javax.swing.JPanel();
        atributosLabel = new javax.swing.JLabel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jListAtributos = new javax.swing.JList();
        atributosAnadir = new javax.swing.JButton();
        atributosModificar = new javax.swing.JButton();
        atributosEliminar = new javax.swing.JButton();
        jMenuBar = new javax.swing.JMenuBar();
        jMenuArchivo = new javax.swing.JMenu();
        salirMenuItem = new javax.swing.JMenuItem();
        jMenuAyuda = new javax.swing.JMenu();
        acercaDeMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Prácticas DPOO");
        setMinimumSize(new java.awt.Dimension(800, 600));

        statusBar.setText("jLabel1");
        getContentPane().add(statusBar, java.awt.BorderLayout.PAGE_END);

        jToolBar.setRollover(true);

        toggleGroup.add(toggleSeleccionar);
        toggleSeleccionar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/dpoo/gui/Selector.gif"))); // NOI18N
        toggleSeleccionar.setSelected(true);
        toggleSeleccionar.setToolTipText("Seleccionar");
        toggleSeleccionar.setFocusable(false);
        toggleSeleccionar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        toggleSeleccionar.setMaximumSize(new java.awt.Dimension(32, 32));
        toggleSeleccionar.setMinimumSize(new java.awt.Dimension(32, 32));
        toggleSeleccionar.setPreferredSize(new java.awt.Dimension(32, 32));
        toggleSeleccionar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toggleSeleccionar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                toggleSeleccionar(evt);
            }
        });
        jToolBar.add(toggleSeleccionar);

        toggleGroup.add(toggleClase);
        toggleClase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/dpoo/gui/Class.gif"))); // NOI18N
        toggleClase.setToolTipText("Crear clase");
        toggleClase.setFocusable(false);
        toggleClase.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        toggleClase.setMaximumSize(new java.awt.Dimension(32, 32));
        toggleClase.setMinimumSize(new java.awt.Dimension(32, 32));
        toggleClase.setPreferredSize(new java.awt.Dimension(32, 32));
        toggleClase.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toggleClase.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                toggleClase(evt);
            }
        });
        jToolBar.add(toggleClase);

        toggleGroup.add(toggleHerencia);
        toggleHerencia.setIcon(new javax.swing.ImageIcon(getClass().getResource("/dpoo/gui/Generalization.gif"))); // NOI18N
        toggleHerencia.setToolTipText("Crear herencia");
        toggleHerencia.setFocusable(false);
        toggleHerencia.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        toggleHerencia.setMaximumSize(new java.awt.Dimension(32, 32));
        toggleHerencia.setMinimumSize(new java.awt.Dimension(32, 32));
        toggleHerencia.setPreferredSize(new java.awt.Dimension(32, 32));
        toggleHerencia.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toggleHerencia.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                toggleHerencia(evt);
            }
        });
        jToolBar.add(toggleHerencia);

        compilar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/dpoo/gui/build.gif"))); // NOI18N
        compilar.setFocusable(false);
        compilar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        compilar.setMaximumSize(new java.awt.Dimension(32, 32));
        compilar.setMinimumSize(new java.awt.Dimension(32, 32));
        compilar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        compilar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                compilarActionPerformed(evt);
            }
        });
        jToolBar.add(compilar);

        getContentPane().add(jToolBar, java.awt.BorderLayout.PAGE_START);

        jSplitPane.setDividerLocation(285);
        jSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

        jEditorPane.setEditable(false);
        jEditorPane.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jEditorPaneMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(jEditorPane);

        jSplitPane.setTopComponent(jScrollPane2);

        jScrollPaneClase.setMinimumSize(new java.awt.Dimension(479, 163));
        jScrollPaneClase.setPreferredSize(new java.awt.Dimension(479, 163));

        jPanelClase.setMinimumSize(new java.awt.Dimension(331, 174));
        jPanelClase.setPreferredSize(new java.awt.Dimension(479, 160));

        claseNombreLabel.setFont(new java.awt.Font("Dialog", 1, 12));
        claseNombreLabel.setText("Nombre:");

        claseHeredaDeLabel.setFont(new java.awt.Font("Dialog", 1, 12));
        claseHeredaDeLabel.setText("Hereda de:");

        claseVisiLabel.setFont(new java.awt.Font("Dialog", 1, 12));
        claseVisiLabel.setText("Visibilidad:");

        visibilidadGroup.add(claseVisiPublica);
        claseVisiPublica.setText("Pública");

        visibilidadGroup.add(claseVisiPrivada);
        claseVisiPrivada.setText("Privada");

        visibilidadGroup.add(claseVisiPaquete);
        claseVisiPaquete.setSelected(true);
        claseVisiPaquete.setText("Paquete");

        visibilidadGroup.add(claseVisiProtegido);
        claseVisiProtegido.setText("Protegido");

        claseModLabel.setFont(new java.awt.Font("Dialog", 1, 12));
        claseModLabel.setText("Modificadores:");

        claseModAbstracta.setText("Abstracta");

        claseModFinal.setText("Final");

        claseRestaurar.setText("Restaurar");
        claseRestaurar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                claseRestaurarActionPerformed(evt);
            }
        });

        claseGuardar.setText("Guardar");
        claseGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                claseGuardarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelClaseLayout = new javax.swing.GroupLayout(jPanelClase);
        jPanelClase.setLayout(jPanelClaseLayout);
        jPanelClaseLayout.setHorizontalGroup(
            jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelClaseLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelClaseLayout.createSequentialGroup()
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(claseNombreLabel)
                            .addComponent(claseHeredaDeLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(claseNombre, javax.swing.GroupLayout.DEFAULT_SIZE, 607, Short.MAX_VALUE)
                            .addComponent(claseHeredaDe, javax.swing.GroupLayout.DEFAULT_SIZE, 607, Short.MAX_VALUE)))
                    .addGroup(jPanelClaseLayout.createSequentialGroup()
                        .addComponent(claseVisiLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(claseVisiPrivada)
                            .addComponent(claseVisiPaquete))
                        .addGap(18, 18, 18)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(claseVisiProtegido)
                            .addComponent(claseVisiPublica)))
                    .addGroup(jPanelClaseLayout.createSequentialGroup()
                        .addComponent(claseModLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(claseModAbstracta)
                            .addComponent(claseModFinal))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 318, Short.MAX_VALUE)
                        .addComponent(claseGuardar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(claseRestaurar)))
                .addContainerGap())
        );
        jPanelClaseLayout.setVerticalGroup(
            jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelClaseLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(claseNombreLabel)
                    .addComponent(claseNombre, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(claseHeredaDe, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(claseHeredaDeLabel))
                .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanelClaseLayout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(claseVisiLabel)
                            .addComponent(claseVisiPaquete)
                            .addComponent(claseVisiProtegido))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(claseVisiPrivada)
                            .addComponent(claseVisiPublica))
                        .addGap(0, 0, 0)
                        .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(claseModAbstracta)
                            .addComponent(claseModLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(claseModFinal)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))
                    .addGroup(jPanelClaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(claseRestaurar)
                        .addComponent(claseGuardar)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jScrollPaneClase.setViewportView(jPanelClase);

        jTabbedPane1.addTab("Clase", jScrollPaneClase);

        jScrollPaneMetodos.setMinimumSize(new java.awt.Dimension(479, 163));

        jPanelMetodos.setPreferredSize(new java.awt.Dimension(476, 160));

        metodosLabel.setFont(new java.awt.Font("Dialog", 1, 12));
        metodosLabel.setText("Métodos:");

        jListMetodos.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListMetodosValueChanged(evt);
            }
        });
        jScrollPane3.setViewportView(jListMetodos);

        metodosAnadir.setText("Añadir");
        metodosAnadir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                metodosAnadir(evt);
            }
        });

        metodosModificar.setText("Modificar");
        metodosModificar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                metodosModificar(evt);
            }
        });

        metodosEliminar.setText("Eliminar");
        metodosEliminar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                metodosEliminar(evt);
            }
        });

        javax.swing.GroupLayout jPanelMetodosLayout = new javax.swing.GroupLayout(jPanelMetodos);
        jPanelMetodos.setLayout(jPanelMetodosLayout);
        jPanelMetodosLayout.setHorizontalGroup(
            jPanelMetodosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelMetodosLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelMetodosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 684, Short.MAX_VALUE)
                    .addComponent(metodosLabel)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelMetodosLayout.createSequentialGroup()
                        .addComponent(metodosAnadir)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(metodosModificar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(metodosEliminar)))
                .addContainerGap())
        );
        jPanelMetodosLayout.setVerticalGroup(
            jPanelMetodosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelMetodosLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(metodosLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelMetodosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(metodosEliminar)
                    .addComponent(metodosModificar)
                    .addComponent(metodosAnadir))
                .addContainerGap())
        );

        jScrollPaneMetodos.setViewportView(jPanelMetodos);

        jTabbedPane1.addTab("Métodos", jScrollPaneMetodos);

        jPanelAtributos.setPreferredSize(new java.awt.Dimension(476, 160));

        atributosLabel.setFont(new java.awt.Font("Dialog", 1, 12));
        atributosLabel.setText("Atributos:");

        jListAtributos.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListAtributosValueChanged(evt);
            }
        });
        jScrollPane4.setViewportView(jListAtributos);

        atributosAnadir.setText("Añadir");
        atributosAnadir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                atributosAnadir(evt);
            }
        });

        atributosModificar.setText("Modificar");
        atributosModificar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                atributosModificar(evt);
            }
        });

        atributosEliminar.setText("Eliminar");
        atributosEliminar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                atributosEliminar(evt);
            }
        });

        javax.swing.GroupLayout jPanelAtributosLayout = new javax.swing.GroupLayout(jPanelAtributos);
        jPanelAtributos.setLayout(jPanelAtributosLayout);
        jPanelAtributosLayout.setHorizontalGroup(
            jPanelAtributosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelAtributosLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelAtributosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 684, Short.MAX_VALUE)
                    .addComponent(atributosLabel)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelAtributosLayout.createSequentialGroup()
                        .addComponent(atributosAnadir)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(atributosModificar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(atributosEliminar)))
                .addContainerGap())
        );
        jPanelAtributosLayout.setVerticalGroup(
            jPanelAtributosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelAtributosLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(atributosLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelAtributosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(atributosEliminar)
                    .addComponent(atributosModificar)
                    .addComponent(atributosAnadir))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jScrollPaneAtributos.setViewportView(jPanelAtributos);

        jTabbedPane1.addTab("Atributos", jScrollPaneAtributos);

        jSplitPane.setBottomComponent(jTabbedPane1);

        getContentPane().add(jSplitPane, java.awt.BorderLayout.CENTER);

        jMenuArchivo.setText("Archivo");

        salirMenuItem.setText("Salir");
        salirMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                salirMenuItemActionPerformed(evt);
            }
        });
        jMenuArchivo.add(salirMenuItem);

        jMenuBar.add(jMenuArchivo);

        jMenuAyuda.setText("Ayuda");

        acercaDeMenuItem.setText("Acerca de");
        acercaDeMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                acercaDeMenuItem(evt);
            }
        });
        jMenuAyuda.add(acercaDeMenuItem);

        jMenuBar.add(jMenuAyuda);

        setJMenuBar(jMenuBar);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    
    /**
     * Inicializa el chequeo del nombre del Atributo en el AtributoDialog
     */
    private void initCheckNombre() {
        //estoy al tanto de los cambios que ocurrieran en el nombre del atributo
        Document doc = this.claseNombre.getDocument();
        doc.addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent arg0) {
                nombreTextChange();
            }

            public void removeUpdate(DocumentEvent arg0) {
                nombreTextChange();
            }

            public void changedUpdate(DocumentEvent arg0) {
                nombreTextChange();
            }
        });
    }
    
    
    private void jEditorPaneMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jEditorPaneMouseClicked
        this.control.ventanaPrincipalMouseClicked(evt);
    }//GEN-LAST:event_jEditorPaneMouseClicked

    private void toggleSeleccionar(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_toggleSeleccionar
        this.control.cambiarModoSeleccionar();
    }//GEN-LAST:event_toggleSeleccionar
    
    private void toggleClase(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_toggleClase
        this.control.cambiarModoClase();
    }//GEN-LAST:event_toggleClase
    
    private void toggleHerencia(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_toggleHerencia
        this.control.cambiarModoHerencia();
    }//GEN-LAST:event_toggleHerencia
    
    private void metodosAnadir(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_metodosAnadir
        //creo un nuevo MetodoDialog y lo hago modal
        MetodoDialog metodoDialog = new MetodoDialog(this, true);
        metodoDialog.setVisible(true);
        
        //recojo el Metodo que hubiera en el MetodoDialog y libero recursos
        Metodo metodo = metodoDialog.getMetodo();
        metodoDialog.dispose();
        
        //¿hay un objeto o el usuario ha pulsado en cancelar?
        if(metodo != null) {
            //añado el método al conjunto de metodos de la FiguraClase
            Vector<Metodo> vMetodos = this.claseSeleccionada.getMetodos();
            vMetodos.add(metodo);
            
            //añado el método al modelo de la JList
            this.metodosListModel.addElement(metodo);
            
            //repinto la lista de métodos de la UI para que se refleje el nuevo método
            this.jListMetodos.repaint();
            
            //repinto la clase
            this.claseSeleccionada.repaint();
        }
    }//GEN-LAST:event_metodosAnadir

    private void metodosModificar(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_metodosModificar
        //obtengo un puntero al Metodo seleccionado en el JList
        Metodo metodo = (Metodo) this.jListMetodos.getSelectedValue();
        
        //creo un nuevo MetodoDialog y le cargo el Metodo anterior
        MetodoDialog metodoDialog = new MetodoDialog(this, true, metodo);
        metodoDialog.setVisible(true);
        
        //al volver aquí el control, el MetodoDialog debe haber modificado el Metodo del cual le pasé la referencia
        //solo queda entonces liberar recursos
        metodoDialog.dispose();
        
        //repinto la lista de métodos de la UI para que se refleje el nuevo método
        this.jListMetodos.repaint();
                    
        //repinto la clase
        this.claseSeleccionada.repaint();
    }//GEN-LAST:event_metodosModificar
    
    private void metodosEliminar(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_metodosEliminar
        //obtengo un puntero al Metodo seleccionado en el JList
        Metodo metodo = (Metodo) this.jListMetodos.getSelectedValue();
        
        //obtengo un puntero al vector de modos de la FiguraClase seleccionada
        Vector<Metodo> vMetodos = this.claseSeleccionada.getMetodos();
        
        //elimino el Metodo tanto en el DefaultListModel como en el Vector
        this.metodosListModel.removeElement(metodo);
        vMetodos.removeElement(metodo);
        
        //repinto la lista de métodos de la UI para que refleje el cambio
        this.jListMetodos.repaint();
            
        //repinto la clase
        this.claseSeleccionada.repaint();
    }//GEN-LAST:event_metodosEliminar
    
    private void atributosAnadir(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_atributosAnadir
        //creo un nuevo AtributoDialog y lo hago modal
        AtributoDialog atributoDialog = new AtributoDialog(this, true);
        atributoDialog.setVisible(true);
        
        //recojo el Atributo que hubiera en el AtributoDialog y libero recursos
        Atributo atributo = atributoDialog.getAtributo();
        atributoDialog.dispose();
        
        //¿hay un objeto o el usuario ha pulsado en cancelar?
        if(atributo != null) {
            //añado el método al conjunto de metodos de la FiguraClase
            Vector<Atributo> vAtributos = this.claseSeleccionada.getAtributos();
            vAtributos.add(atributo);
            
            //añado el método al modelo de la JList
            this.atributosListModel.addElement(atributo);
            
            //repinto la lista de métodos de la UI para que se refleje el nuevo método
            this.jListAtributos.repaint();
            
            //repinto la clase
            this.claseSeleccionada.repaint();
        }
    }//GEN-LAST:event_atributosAnadir
    
    private void atributosModificar(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_atributosModificar
        //obtengo un punto al Atributo seleccionado en el JList
        Atributo atributo = (Atributo) this.jListAtributos.getSelectedValue();
        
        //creo un nuevo AtributoDialog y le cargo el Atributo anterior
        AtributoDialog atributoDialog = new AtributoDialog(this, true, atributo);
        atributoDialog.setVisible(true);
        
        //libero recursos del AtributoDialog
        atributoDialog.dispose();
        
        //repinto la lista de métodos de la UI para que se refleje el nuevo método
        this.jListAtributos.repaint();
        
        //repinto la clase
        this.claseSeleccionada.repaint();
    }//GEN-LAST:event_atributosModificar
    
    private void atributosEliminar(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_atributosEliminar
        //obtengo un puntero al Atributo seleccionado en el JList
        Atributo atributo = (Atributo) this.jListAtributos.getSelectedValue();
        
        //obtengo un puntero al vector de atributos de la FiguraClase seleccionada
        Vector<Atributo> vAtributos = this.claseSeleccionada.getAtributos();
        
        //elimino el Metodo tanto en el DefaultListModel como en el Vector
        this.atributosListModel.removeElement(atributo);
        vAtributos.removeElement(atributo);
        
        //repinto la lista de métodos de la UI para que refleje el cambio
        this.jListAtributos.repaint();
        
        //repinto la clase
        this.claseSeleccionada.repaint();
    }//GEN-LAST:event_atributosEliminar
    
    private void acercaDeMenuItem(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_acercaDeMenuItem
        this.acercaDeDialog.setVisible(true);
    }//GEN-LAST:event_acercaDeMenuItem

    private void salirMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_salirMenuItemActionPerformed
        System.exit(0);
    }//GEN-LAST:event_salirMenuItemActionPerformed
    
    private void claseGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_claseGuardarActionPerformed
        if(this.comprobarNombre()) {
            //guardo el nombre
            this.claseSeleccionada.setNombre(this.claseNombre.getText());

            //los modificadores de comportamiento
            ModVisi modVisi = this.claseSeleccionada.getModVisi();
            modVisi.setModAbstracto(this.claseModAbstracta.isSelected());
            modVisi.setModFinal(this.claseModFinal.isSelected());

            //los de visibilidad
            //esto es una ÑAPA, pero es necesario porque el diseño de swing para los ButtonGroup es una mierda
            if(this.claseVisiPaquete.isSelected()) {
                modVisi.setVisibilidad(ModVisi.PAQUETE);
            }
            if(this.claseVisiPrivada.isSelected()) {
                modVisi.setVisibilidad(ModVisi.PRIVADO);
            }
            if(this.claseVisiProtegido.isSelected()) {
                modVisi.setVisibilidad(ModVisi.PROTEGIDO);
            }
            if(this.claseVisiPublica.isSelected()) {
                modVisi.setVisibilidad(ModVisi.PUBLICO);
            }
            
            //repinto la clase
            this.claseSeleccionada.repaint();
        } else {
            //el nombre no es correcto, tiro un mensaje de error
            this.nombreTextChange();
        }
    }//GEN-LAST:event_claseGuardarActionPerformed

    private void claseRestaurarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_claseRestaurarActionPerformed
        //vuelvo a cargar en el panel la información de la FiguraClase
        this.rellenarPanelClase();
    }//GEN-LAST:event_claseRestaurarActionPerformed

private void jListMetodosValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListMetodosValueChanged
    if(this.jListMetodos.getSelectedIndex() == -1) {
        this.metodosModEliSetEnabled(false);
    } else {
        this.metodosModEliSetEnabled(true);
    }
}//GEN-LAST:event_jListMetodosValueChanged

private void jListAtributosValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListAtributosValueChanged
    if(this.jListAtributos.getSelectedIndex() == -1) {
        this.atributosModEliSetEnabled(false);
    } else {
        this.atributosModEliSetEnabled(true);
    }
}//GEN-LAST:event_jListAtributosValueChanged

private void compilarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_compilarActionPerformed
    System.out.println(this.claseSeleccionada);
}//GEN-LAST:event_compilarActionPerformed

    
    /**
     * Añade un JComponent al tapiz de la UI
     * @param componente
     */
    public void anadirJComponent(JComponent componente) {
        this.jEditorPane.add(componente);
        this.jEditorPane.repaint();
    }
    
    
    /**
     * Muestra la información de la clase seleccionada en la UI
     * @param clase
     */
    public void mostrarInfoFiguraClase(FiguraClase clase) {
        if(clase != null) {
            //guardo una referencia de la FiguraClase seleccionada
            this.claseSeleccionada = clase;
            
            //activo los elementos de la UI que van a mostrar información
            this.panelClaseSetEnabled(true);
            this.panelAtributosSetEnabled(true);
            this.panelMetodosSetEnabled(true);
            
            //y los relleno
            this.rellenarPanelClase();
            this.rellenarPanelAtributos();
            this.rellenarPanelMetodos();
            
        } else {
            this.panelClaseSetEnabled(false);
            this.panelMetodosSetEnabled(false);
            this.metodosModEliSetEnabled(false);
            this.panelAtributosSetEnabled(false);
            this.atributosModEliSetEnabled(false);
            
            this.claseSeleccionada = null;
        }
    }
    
    
    
    // FUNCIONES QUE CONTROLAN LA ACTIVACIÓN Y DESACTIVACIÓN DE ELEMENTOS DE LA UI
    /**
     * Activa/desactiva el panel de información de la clase de la interfaz gráfica
     */
    private void panelClaseSetEnabled(boolean arg) {
        this.claseNombreLabel.setEnabled(arg);
        this.claseNombre.setEnabled(arg);
        this.claseHeredaDeLabel.setEnabled(arg);
        this.claseHeredaDe.setEnabled(arg);
        this.claseModLabel.setEnabled(arg);
        this.claseModAbstracta.setEnabled(arg);
        this.claseModFinal.setEnabled(arg);
        this.claseVisiLabel.setEnabled(arg);
        this.claseVisiPaquete.setEnabled(arg);
        this.claseVisiPrivada.setEnabled(arg);
        this.claseVisiProtegido.setEnabled(arg);
        this.claseVisiPublica.setEnabled(arg);
        this.claseGuardar.setEnabled(arg);
        this.claseRestaurar.setEnabled(arg);
    }

    
    /**
     * Activa/desactiva el panel de métodos de la interfaz gráfica
     */
    private void panelMetodosSetEnabled(boolean arg) {
        this.metodosLabel.setEnabled(arg);
        this.jListMetodos.setEnabled(arg);
        this.metodosAnadir.setEnabled(arg);
    }

    
    /**
     * Activa/desactiva el panel de atributos de la interfaz gráfica
     */
    private void panelAtributosSetEnabled(boolean arg) {
        this.atributosLabel.setEnabled(arg);
        this.jListAtributos.setEnabled(arg);
        this.atributosAnadir.setEnabled(arg);
    }
    
    
    /**
     * Activa/desactiva los botones de modificar y eliminar métodos
     * @param arg
     */
    private void metodosModEliSetEnabled(boolean arg) {
        this.metodosModificar.setEnabled(arg);
        this.metodosEliminar.setEnabled(arg);
    }
    
    
   /**
    * Activa/desactiva los botones de modificar y eliminar atributos
    * @param arg
    */
    private void atributosModEliSetEnabled(boolean arg) {
        this.atributosModificar.setEnabled(arg);
        this.atributosEliminar.setEnabled(arg);
    }
    
    
    //FUNCIONES QUE RELLENAN INFORMACIÓN DE LA UI 
    /**
     * Rellena el panel de la clase con la info de la FiguraClase seleccionada
     */
    private void rellenarPanelClase() {
        //nombre de la clase
        this.claseNombre.setText(this.claseSeleccionada.getNombre());
        
        //modificadores de visibilidad y de acceso
        ModVisi modVisi = this.claseSeleccionada.getModVisi();
        this.claseModAbstracta.setSelected(modVisi.getModFinal());
        this.claseModFinal.setSelected(modVisi.getModFinal());
        switch(modVisi.getVisibilidad()) {
            case ModVisi.PAQUETE:
                this.claseVisiPaquete.setSelected(true);
                break;
            case ModVisi.PRIVADO:
                this.claseVisiPrivada.setSelected(true);
                break;
            case ModVisi.PROTEGIDO:
                this.claseVisiProtegido.setSelected(true);
                break;
            case ModVisi.PUBLICO:
                this.claseVisiPublica.setSelected(true);
                break;
        }
    }
    
    /**
     * Rellena el panel de métodos con la info de la FiguraClase seleccionada
     */
    private void rellenarPanelMetodos() {
        //por si aca, vacío el modelo
        this.metodosListModel.clear();
        
        //añado los Metodo de la FiguraClase en el modelo de la JList de los métodos
        //como mola el foreach de Java 5
        for(Metodo metodo : this.claseSeleccionada.getMetodos()) {
            this.metodosListModel.addElement(metodo);
        }
    }
    
    /**
     * Rellena el panel de atributos con la info de la FiguraClase seleccionada
     */
    private void rellenarPanelAtributos() {
        //vacío el modelo...
        this.atributosListModel.clear();
        
        //añado los Atributo de la FiguraClase en el modelo de la JList
        for(Atributo atributo : this.claseSeleccionada.getAtributos()) {
            this.atributosListModel.addElement(atributo);
        }
    }

    
    //COMPROBAR QUE EL CONTENIDO DEL nombre de la clase ES CORRECTO
    /**
     * Comprueba que el nombre del Atributo sea correcto
     * @return
     */
    private boolean comprobarNombre() {
        //Debe comenzar con una letra minúscula, y después tener letras, números o _
        Pattern pc = Pattern.compile("\\p{Upper}+\\w*");
        Matcher m = pc.matcher(this.claseNombre.getText());
        
        return m.matches();
    }

    /**
     * Si el nombre del atributo es incorrecto muestra un cuadro de diálogo informando al usuario
     */
    private void nombreTextChange() {
        if(this.comprobarNombre()) {
            //habilito el botón de guardar
            this.claseGuardar.setEnabled(true);
        } else {
            //deshabilito el botón de guardar
            this.claseGuardar.setEnabled(false);
            
            //muestro un mensaje por pantalla informando del error
            String msgText = "<html>Para que el nombre de una clase sea válido, debe cumplir las siguientes condiciones:<ul>" +
                "<li>Debe comenzar con una letra mayúscula (A-Z).</li>" +
                "<li>Constar únicamente de letras (a-z, A-Z), números (0-9) o el caracter _.</li><ul></html>";
            JOptionPane.showMessageDialog(this, msgText, "Nombre de atributo incorrecto", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem acercaDeMenuItem;
    private javax.swing.JButton atributosAnadir;
    private javax.swing.JButton atributosEliminar;
    private javax.swing.JLabel atributosLabel;
    private javax.swing.JButton atributosModificar;
    private javax.swing.JButton claseGuardar;
    private javax.swing.JTextField claseHeredaDe;
    private javax.swing.JLabel claseHeredaDeLabel;
    private javax.swing.JCheckBox claseModAbstracta;
    private javax.swing.JCheckBox claseModFinal;
    private javax.swing.JLabel claseModLabel;
    private javax.swing.JTextField claseNombre;
    private javax.swing.JLabel claseNombreLabel;
    private javax.swing.JButton claseRestaurar;
    private javax.swing.JLabel claseVisiLabel;
    private javax.swing.JRadioButton claseVisiPaquete;
    private javax.swing.JRadioButton claseVisiPrivada;
    private javax.swing.JRadioButton claseVisiProtegido;
    private javax.swing.JRadioButton claseVisiPublica;
    private javax.swing.JButton compilar;
    private javax.swing.JEditorPane jEditorPane;
    private javax.swing.JList jListAtributos;
    private javax.swing.JList jListMetodos;
    private javax.swing.JMenu jMenuArchivo;
    private javax.swing.JMenu jMenuAyuda;
    private javax.swing.JMenuBar jMenuBar;
    private javax.swing.JPanel jPanelAtributos;
    private javax.swing.JPanel jPanelClase;
    private javax.swing.JPanel jPanelMetodos;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JScrollPane jScrollPaneAtributos;
    private javax.swing.JScrollPane jScrollPaneClase;
    private javax.swing.JScrollPane jScrollPaneMetodos;
    private javax.swing.JSplitPane jSplitPane;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JToolBar jToolBar;
    private javax.swing.JButton metodosAnadir;
    private javax.swing.JButton metodosEliminar;
    private javax.swing.JLabel metodosLabel;
    private javax.swing.JButton metodosModificar;
    private javax.swing.ButtonGroup modificadoresGroup;
    private javax.swing.JMenuItem salirMenuItem;
    private javax.swing.JLabel statusBar;
    private javax.swing.JToggleButton toggleClase;
    private javax.swing.ButtonGroup toggleGroup;
    private javax.swing.JToggleButton toggleHerencia;
    private javax.swing.JToggleButton toggleSeleccionar;
    private javax.swing.ButtonGroup visibilidadGroup;
    // End of variables declaration//GEN-END:variables
    
}
